﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.DynamicData;
using System.Web.DynamicData.ModelProviders;
using System.Web.UI.WebControls;
using NotAClue.ComponentModel.DataAnnotations;
using System.Web.UI;

namespace NotAClue.Web.DynamicData
{
    public class SecureMetaTable : MetaTable
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SecureMetaTable"/> class.
        /// </summary>
        /// <param name="metaModel">The meta model.</param>
        /// <param name="tableProvider">The table provider.</param>
        public SecureMetaTable(MetaModel metaModel, TableProvider tableProvider) :
            base(metaModel, tableProvider) { }

        private SecureMetaModel SecureModel { get { return (SecureMetaModel)this.Model; } }

        /// <summary>
        /// Initializes data that may not be available when the constructor is called.
        /// </summary>
        protected override void Initialize() { base.Initialize(); }

        protected override MetaColumn CreateColumn(ColumnProvider columnProvider)
        {
            return new SecureMetaColumn(this, columnProvider);
        }

        protected override MetaChildrenColumn CreateChildrenColumn(ColumnProvider columnProvider)
        {
            return new SecureMetaChildrenColumn(this, columnProvider);
        }

        protected override MetaForeignKeyColumn CreateForeignKeyColumn(ColumnProvider columnProvider)
        {
            return new SecureMetaForeignKeyColumn(this, columnProvider);
        }

        /// <summary>
        /// Gets the page template.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static PageTemplate GetPageTemplate()
        {
            var pageTemplate = PageTemplate.Unknown;
            if (System.Web.HttpContext.Current != null)
            {
                var page = System.Web.HttpContext.Current.Handler as Page;
                pageTemplate = page.GetPageTemplate();
            }
            return pageTemplate;
        }

        /// <summary>
        /// Gets the scaffold columns.
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <param name="containerType">Type of the container.</param>
        /// <returns></returns>
        public override IEnumerable<MetaColumn> GetScaffoldColumns(DataBoundControlMode mode, ContainerType containerType)
        {
            var pageTemplate = GetPageTemplate();
            var secureColumns = GetScaffoldColumns(mode, containerType, pageTemplate, new String[0]);
            return secureColumns;
        }

        /// <summary>
        /// Gets the scaffold columns.
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <param name="containerType">Type of the container.</param>
        /// <returns></returns>
        public IEnumerable<MetaColumn> GetScaffoldColumns(DataBoundControlMode mode, ContainerType containerType, PageTemplate pageTemplate, String[] hideColumns)
        {
            var columns = base.GetScaffoldColumns(mode, containerType);
            var notHiddenInPage = from c in columns
                                  where !c.IsHidden(pageTemplate) && 
                                    !hideColumns.Contains(c.Name) && 
                                    c.ShowChildrenColumn()
                                  select c;

            var secureColumns = from column in notHiddenInPage
                                where column.ColumnIsVisible()
                                select column;
            return secureColumns;
        }


        public override IEnumerable<MetaColumn> GetFilteredColumns()
        {
            var pageTemplate = GetPageTemplate();

            var filteredColumns = base.GetFilteredColumns();
            var filteredColumnsSorted = from f in filteredColumns
                                        where f.FilterIsVisible() && !f.IsFilterHidden(pageTemplate)
                                        orderby f.GetAttributeOrDefault<FilterAttribute>(), f.Name
                                        select f;

            return filteredColumnsSorted;
        }
    }
}
